package com.onluy.framework.tools.utils;

 
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.security.rsa.RSAPublicKeyImpl;

public abstract class EncryptUtil
{
  public static final String SECURITY_KEY = "!@#$%^&*()_+$WALKING_SECURITY_KEY!";

  public static void main(String[] args)
    throws Exception
  {
    System.out.println(encryptByDES("23u2u302u02u0joaejoo343#$%^&*&^%$#$%^&", "!@#$%^&*()_+$WALKING_SECURITY_KEY!"));
  }

  public static String encryptByMD5(String plaintext) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    byte[] data = encryptByMD5(plaintext.getBytes());
    String hexStr = StringUtil.byteArray2HexStr(data);
    return hexStr;
  }

  public static String encryptByMD5(String plaintext, String charset) throws UnsupportedEncodingException, NoSuchAlgorithmException {
    byte[] data = encryptByMD5(plaintext.getBytes(charset));
    String hexStr = StringUtil.byteArray2HexStr(data);
    return hexStr;
  }

  public static byte[] encryptByMD5(byte[] plaintext) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(plaintext);
    byte[] result = md.digest();
    return result;
  }

  private static Key getDESKey(byte[] arrBTmp) throws Exception {
    byte[] arrB = new byte[8];
    for (int i = 0; (i < arrBTmp.length) && (i < arrB.length); i++) {
      arrB[i] = arrBTmp[i];
    }
    Key key = new SecretKeySpec(arrB, "DES");
    return key;
  }

  public static byte[] encryptByDES(byte[] plaintext, String key) throws Exception {
    Cipher encryptCipher = Cipher.getInstance("DES");
    encryptCipher.init(1, getDESKey(key.getBytes()));
    return encryptCipher.doFinal(plaintext);
  }

  public static String encryptByDES(String plaintext, String key) throws Exception {
    byte[] data = encryptByDES(plaintext.getBytes(), key);
    String hexStr = StringUtil.byteArray2HexStr(data);
    return hexStr;
  }

  public static String encryptByDES(String plaintext, String key, String charset) throws Exception {
    byte[] data = encryptByDES(plaintext.getBytes(charset), key);
    String hexStr = StringUtil.byteArray2HexStr(data);
    return hexStr;
  }

  public static byte[] decryptByDES(byte[] crypttext, String key) throws Exception {
    Cipher decryptCipher = Cipher.getInstance("DES");
    decryptCipher.init(2, getDESKey(key.getBytes()));
    return decryptCipher.doFinal(crypttext);
  }

  public static String decryptByDES(String crypttext, String key) throws Exception {
    byte[] data = StringUtil.hexStr2ByteArray(crypttext);
    byte[] result = decryptByDES(data, key);
    return new String(result);
  }

  public static String decryptByDES(String crypttext, String key, String charset) throws Exception {
    byte[] data = StringUtil.hexStr2ByteArray(crypttext);
    byte[] result = decryptByDES(data, key);
    return new String(result, charset);
  }

  public static KeyPair getRSAKeyPair() {
    return getRSAKeyPair(1024);
  }

  public static KeyPair getRSAKeyPair(int length) {
    KeyPairGenerator kpg = null;
    try {
      kpg = KeyPairGenerator.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }

    kpg.initialize(length);

    KeyPair keyPair = kpg.genKeyPair();
    return keyPair;
  }

  public static PublicKey getPublicKey(String modulus, String publicExponent) throws InvalidKeyException {
    PublicKey publicKey = new RSAPublicKeyImpl(new BigInteger(modulus), new BigInteger(publicExponent));
    return publicKey;
  }

  public static String encryptByRSA(String plaintext, Key key) throws Exception {
    byte[] data = encryptByRSA(plaintext.getBytes(), key);
    String hexStr = StringUtil.byteArray2HexStr(data);
    return hexStr;
  }

  public static String encryptByRSA(String plaintext, Key key, String charset) throws Exception {
    byte[] data = encryptByRSA(plaintext.getBytes(charset), key);
    String hexStr = StringUtil.byteArray2HexStr(data);
    return hexStr;
  }

  public static byte[] encryptByRSA(byte[] plaintext, Key key) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(1, key);

    return cipher.doFinal(plaintext);
  }

  public static String decryptByRSA(String crypttext, Key key) throws Exception {
    return decryptByRSA(crypttext, key, System.getProperty("file.encoding"));
  }

  public static String decryptByRSA(String crypttext, Key key, String charset) throws Exception {
    byte[] data = StringUtil.hexStr2ByteArray(crypttext);
    byte[] result = decryptByRSA(data, key);
    return new String(result, charset);
  }

  public static byte[] decryptByRSA(byte[] crypttext, Key key) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(2, key);
    return cipher.doFinal(crypttext);
  }
}